// Code written by Dennis Frie for diyosd
// changed by Stefan Muerzl (stefan [dot] muerzl [at] gmail.com) to add data to line 21
//http://www.phecap.nl/download/enhenced-teletext-specs.pdf
#define align_text 44
#define VbiDataline 30		//only for debug, DEFAULT: 21
#define SPI_DIVIDER 32 
/*
32 = 500kHz
16 = 1MHz
8 = 2MHz
4 = 4MHz
*/

#define DimOn  DDRB |= 0b00000001;
#define DimOff DDRB &= 0b11111110;

#include <avr/delay.h>

int line = 0;
int loopcount = 0;

void setup() {

pinMode(10,OUTPUT);
pinMode(11,OUTPUT);  
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);

pinMode(0,INPUT);  
pinMode(1,INPUT);
pinMode(2,INPUT);
pinMode(3,INPUT);
pinMode(4,INPUT);  
pinMode(5,INPUT);
pinMode(6,INPUT); 
pinMode(7,INPUT);
pinMode(8,INPUT);  
pinMode(9,INPUT);
 
#if SPI_DIVIDER == 32// Set SPI to 500kHz
  SPCR = (0<<SPIE)|(1<<SPE) |(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(0<<SPR0);
  SPSR = (1<<SPI2X); 
#endif 
#if SPI_DIVIDER == 16// Set SPI to 1MHz
  SPCR = (0<<SPIE)|(1<<SPE) |(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(0<<SPR1)|(1<<SPR0);
  SPSR = (0<<SPI2X); 
#endif 
#if SPI_DIVIDER == 8// Set SPI to 2MHz
  SPCR = (0<<SPIE)|(1<<SPE) |(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(0<<SPR1)|(1<<SPR0);
  SPSR = (1<<SPI2X); 
#endif 
#if SPI_DIVIDER == 4// Set SPI to 4MHz
  SPCR = (0<<SPIE)|(1<<SPE) |(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(0<<SPR1)|(0<<SPR0);
  SPSR = (0<<SPI2X);  
#endif 


SPDR =0b00000000;  // IMPORTANT.. The SPI will idle random at low or high in the beginning. 
  
TIMSK0=0;
TIMSK1=0;
TIMSK2=0;

  // Init analog comparator to register new line and frame
  ADCSRB = 0b00000001; // Set analog comparator mode
  
  ACSR = 0b00001011; //Enable Analog comparator interrupt 
  // Set interrupt on falling output edge.
  
  ADCSRA|=(1<<ADSC);    
  
// Start timer 2 - used to determine if it's a new frame or line. 
  TCCR2B =
  (0<<CS22) | //Prescale 1024
  (0<<CS21) | //Prescale 1024
  (1<<CS20) | //Prescale 1024
  (0<<WGM22); // CTC mode (Clear timer on compare match)  

}

// Analog comparator interrupt:
ISR(ANALOG_COMP_vect) {
       // Reset counter
       TCNT2 =0; 

       // Wait for the sync to go high again;
       while ((ACSR & 0b00100000) == 0b00100000) { }  
      
      // If the counter has exceeded the "new line sync time", it's a new 
      // frame. In that case, we just need to reset the line-counter.  
      // 
      if (TCNT2 > 75) {
      line = 0;
      }  
  
 detectline(); 
}

void detectline() {
        
// ============================================================
// Data-Insert
// ============================================================ 
        
if (line > VbiDataline && line < (VbiDataline+30)) {      


  _delay_loop_1(align_text);
  
  DimOn;
  
  // Shift out first 8 bit
  SPDR = 'A';	//A
  while (!(SPSR & (1<<SPIF)))  {     // Wait for the end of the transmission
  };
  
  
  // Shift out second 8 bit
  SPDR = 0b00000000;	//empty                   
  while (!(SPSR & (1<<SPIF)))  {     // Wait for the end of the transmission
  };	
  
  // Shift out third 8 bit
  SPDR = '1';	//A	 
  while (!(SPSR & (1<<SPIF)))  {     // Wait for the end of the transmission
  };	
  SPDR = 0b00000000;
 	
  
	
  DimOff;
		 
 } 
// ============================================================
// Data-Insert
// ============================================================  

if (line == 290) {
	loopcount++;		//loopcount only used to see atmega is running or not
		 
	if (loopcount == 10) {
		loopcount=0;
	} 

}

	// Increase line count..
   line++;

    // Let's make sure SPI is not idling high.
   SPDR=0b00000000;      
          
}

void loop() {

		//toogle a led to see that it's running
		if (loopcount < 5){
			digitalWrite(13, HIGH);
		}
		else{
			digitalWrite(13,LOW);
		}
		
	}

